package aceim.app.view.page; import java.lang.reflect.Constructor; import java.util.List; import aceim.api.dataentity.Buddy; import aceim.api.dataentity.EntityWithID; import aceim.api.dataentity.InputFormFeature; import aceim.api.dataentity.OnlineInfo; import aceim.api.dataentity.PersonalInfo; import aceim.api.service.ApiConstants; import aceim.api.utils.Logger; import aceim.api.utils.Logger.LoggerLevel; import aceim.app.MainActivity; import aceim.app.dataentity.Account; import aceim.app.dataentity.ProtocolResources; import aceim.app.dataentity.listeners.IHasAccount; import aceim.app.dataentity.listeners.IHasBuddy; import aceim.app.screen.Screen; import aceim.app.utils.LinqRules.AccountByProtocolUidLinqRule; import aceim.app.utils.LinqRules.ChatLinqRule; import aceim.app.utils.LinqRules.PageIdLinqRule; import aceim.app.utils.LinqRules.PersonalInfoLinqRule; import aceim.app.utils.ViewUtils; import aceim.app.utils.linq.KindaLinq; import aceim.app.utils.linq.KindaLinqRule; import aceim.app.view.page.about.About; import aceim.app.view.page.accounteditor.AccountEditor; import aceim.app.view.page.accounts.Accounts; import aceim.app.view.page.chat.Chat; import aceim.app.view.page.contactlist.ContactList; import aceim.app.view.page.history.History; import aceim.app.view.page.inputform.InputFormFeaturePage; import aceim.app.view.page.other.GlobalMessage; import aceim.app.view.page.other.MasterPassword; import aceim.app.view.page.other.SearchResult; import aceim.app.view.page.other.Splash; import aceim.app.view.page.personalinfo.PersonalInfoPage; import aceim.app.view.page.transfers.FileTransfers; import aceim.app.view.page.utils.Utilities; import aceim.app.widgets.bottombar.BottomBarButtonInfo; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; public abstract class Page extends Fragment { private MainActivity mActivity; private View cachedView = null; private Bundle cachedBundle = null; public abstract Drawable getIcon(Context context); public abstract String getTitle(Context context); protected abstract View createView(LayoutInflater inflater, ViewGroup group, Bundle saved); protected final OnClickListener mRemoveMeClickListener = new OnClickListener() { @Override public void onClick(View v) { removeMe(); } }; protected Page() { setRetainInstance(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved){ if (cachedView == null) { cachedView = createView(inflater, group, cachedBundle); cachedBundle = null; } else { if (cachedView.getParent() != null) { ((ViewGroup)cachedView.getParent()).removeView(cachedView); } } onSetMeSelected(); return cachedView; } @Override public boolean onOptionsItemSelected(MenuItem item){ return true; } public String getPageId() { if (this instanceof Chat || this instanceof History){ return getPageIdForEntityWithId(this.getClass(), ((IHasBuddy)this).getBuddy()); } else if (this instanceof ContactList || this instanceof FileTransfers){ return getPageIdForEntityWithId(this.getClass(), ((IHasAccount)this).getAccount()); } return getClass().getSimpleName(); } protected void removeMe() { onLeaveMe(); this.cachedView = null; remove(getMainActivity().getScreen(), this); } public static void addPasswordPage(Screen screen) { screen.addPage(new MasterPassword(), true); } public static void getContactListPage(MainActivity activity, Account account) { Screen screen = activity.getScreen(); Page page = getPage(screen, new PageIdLinqRule(getPageIdForEntityWithId(ContactList.class, account))); if (page == null) { page = ContactList.createContactListPage(activity, account); if (page != null) screen.addPage(page, true); } else { screen.setSelectedPage(page.getPageId()); } } public static void addSplash(Screen screen) { screen.addPage(new Splash(), true); } public static void addAccountManagerPage(Screen screen, List<Account> accounts) { screen.addPage(new Accounts(accounts), true); } public interface PageChangedListener { public void onPageChanged(String pageId); } public static void removeSplash(Screen screen) { Page splash = screen.findPage(Splash.class.getSimpleName()); if (splash != null) { screen.removePage(splash); } } public static void remove(Screen screen, Page page) { screen.removePage(page); if (page instanceof IHasAccount) { getContactListPage(screen.getActivity(), ((IHasAccount)page).getAccount()); } } public static void addMessagePage(Screen screen, String title, Drawable icon, int textId, List<BottomBarButtonInfo> buttons) { screen.addPage(new GlobalMessage(title, icon, textId, buttons), true); } public static void addAccountEditorPage(Screen screen, Account account) { screen.addPage(new AccountEditor(account), true); } public static void addSearchResultPage(Screen screen, Account account, List<PersonalInfo> infoList, boolean setAsCurent) { screen.addPage(new SearchResult(account, infoList), true); } public static void getChatPage(Screen screen, Buddy buddy, Account account) { Page page = getPage(screen, new ChatLinqRule(buddy)); if (page == null) { screen.addPage(new Chat(buddy, account, screen.getActivity().getProtocolResourcesForAccount(account)), true); } else { screen.setSelectedPage(page.getPageId()); } } public static void getHistoryPage(Screen screen, Buddy buddy) { Page page = getPage(screen, new PageIdLinqRule(getPageIdForEntityWithId(History.class, buddy))); if (page == null) { screen.addPage(new History(buddy), true); } else { screen.setSelectedPage(page.getPageId()); } } public static void getInputFormPage(MainActivity mainActivity, InputFormFeature iff, OnlineInfo info, ProtocolResources resources) { Screen screen = mainActivity.getScreen(); Page page = getPage(screen, new PageIdLinqRule(getPageIdForInputFormPage(iff, info))); if (page == null) { screen.addPage(new InputFormFeaturePage(iff, info, resources), true); } else { screen.setSelectedPage(page.getPageId()); } } public static void getUtilsPage(Screen screen) { Page page = getPage(screen, new PageIdLinqRule(Utilities.class.getSimpleName())); if (page == null) { screen.addPage(new Utilities(), true); } else { screen.setSelectedPage(page.getPageId()); } } public static void getAboutPage(Screen screen) { Page page = getPage(screen, new PageIdLinqRule(About.class.getSimpleName())); if (page == null) { screen.addPage(new About(), true); } else { screen.setSelectedPage(page.getPageId()); } } public static void getFileTransfersPage(Screen screen, Account account) { Page page = getPage(screen, new PageIdLinqRule(getPageIdForEntityWithId(FileTransfers.class, account))); if (page == null) { screen.addPage(new FileTransfers(account), false); } else { screen.setSelectedPage(page.getPageId()); } } public static void getPersonalInfoPage(Screen screen, PersonalInfo info) { Page page = getPage(screen, new PersonalInfoLinqRule(info)); if (page == null) { screen.addPage(new PersonalInfoPage(info), true); } else { screen.setSelectedPage(page.getPageId()); } } private static Page getPage(Screen screen, KindaLinqRule<Page> rule) { List<Page> pages = screen.findPagesByRule(rule); if (pages.size() < 1) { return null; } else { return pages.get(0); } } public static <T> String getPageIdForEntityWithId(Class<T> classOfT, EntityWithID entity) { return classOfT.getSimpleName() + " " + entity.getEntityId(); } public static String getPageIdForInputFormPage(InputFormFeature iff, OnlineInfo info) { return iff.getFeatureId() + " " + info.getProtocolUid() + " " + info.getServiceId(); } @SuppressWarnings("unchecked") public static void recoverPageById(List<Account> accounts, String pageId, Bundle savedState, MainActivity mainActivity) { Logger.log("Recovering page " + pageId, LoggerLevel.VERBOSE); String[] pageIdParts = pageId.split(Character.toString(ApiConstants.GENERAL_DIVIDER)); Class<? extends Page> pageClass = ViewUtils.getPageClassByPageId(pageIdParts[0]); if (pageClass == null) { return; } Constructor<? extends Page> c = (Constructor<? extends Page>) pageClass.getConstructors()[0]; Class<?>[] params = c.getParameterTypes(); Object[] args = new Object[params.length]; Page page; for (int i = 0; i<params.length; i++) { Class<?> param = params[i]; //TODO refactor? Account a = KindaLinq.from(accounts).where(new AccountByProtocolUidLinqRule(pageIdParts[1])).first(); if (param == Account.class) { if (a == null) return; args[i] = a; } else if (param == Buddy.class) { if (a == null) return; Buddy b = a.getBuddyByProtocolUid(pageIdParts[3]); if (b == null) return; args[i] = b; } else if (param == ProtocolResources.class) { if (a == null) return; ProtocolResources res = mainActivity.getProtocolResourcesForAccount(a); if (res == null) return; args[i] = res; } } try { page = c.newInstance(args); } catch (Exception e) { Logger.log(e); return; } page.cachedBundle = savedState; mainActivity.getScreen().addPage(page, false); } public void setMainActivity(MainActivity activity){ this.mActivity = activity; } protected MainActivity getMainActivity() { if (mActivity == null) { try { while ((mActivity = (MainActivity) getActivity()) == null) { Thread.sleep(100); } } catch (InterruptedException e) { Logger.log(e); } } return mActivity; } public boolean onKeyDown(int i, KeyEvent event) { if (i == KeyEvent.KEYCODE_BACK) { removeMe(); return true; } return false; } public boolean hasMenu() { return false; } public Bundle getPageDataForStorage() { return null; } public void onSetMeSelected() {} public void onLeaveMe() {} }